package cn.i7baozh.alibaba.sentinel.origin;

import com.alibaba.csp.sentinel.adapter.spring.webmvc_v6x.callback.RequestOriginParser;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * 针对
 * 1. sentinel中的流控规则中的来源
 * 2. sentinel中的授权规则
 * 这两种场景，让程序知道“来源”是怎么判断的
 *
 * @author zhangbaoqi532
 * @date 2024/12/30
 */
@Component
public class OriginService implements RequestOriginParser {
    /**
     * 从request对象中，获取到请求者的origin值并返回。
     * 这个值完全是业务定义的，想从header里取也行，想从param中取也行，都行。
     * 最终的意思就是如果是从张三处调取我这里获取到某个标识为张三，从李四哪里就是李四。
     * 然后我通过授权规则里可以对张三限流，李四不限制
     * <p>
     * 例如下面的例子如果我在授权规则中添加：
     * 资源名: /alibaba/sentinel/getA
     * 流控应用: testA,testB
     * 授权类型: 白名单
     * 那么请求/alibaba/sentinel/getA?xxxOrigin=testA 或 xxxOrigin=testB都是可以访问的
     * xxxOrigin=testC访问失败
     *
     * @param httpServletRequest
     * @return
     */
    @Override
    public String parseOrigin(HttpServletRequest httpServletRequest) {
        String xxxOrigin = httpServletRequest.getHeader("xxxOrigin");
        if (xxxOrigin == null || xxxOrigin.length() <= 0) {
            xxxOrigin = httpServletRequest.getParameter("xxxOrigin");
        }
        System.out.println("xxxOrigin: " + xxxOrigin);
        // 这里如果拿不到来源字段 应该给个默认的 并且对这个默认的做个黑名单或白名单的默认规则 否则调用方不传递这个值的时候是限制不住的
        return Objects.nonNull(xxxOrigin) ? xxxOrigin : "esdd";
    }
}
